ArmBob v.1.02 Tutorial 2                               GCW 06/06/94

Accounts   1
------------
We will now try something more ambitious for our second program -
modelling a bank account. This time, instead of writing the program
as a single file, we will write it as three textfiles, one for defining
the class of accounts, one for providing the notion of "hidden input",
useful for entering passwords, and another for the main program.

If you SHIFT double-click on! Account you will see that
it has a file !RunImage, of type Bob, that contains the function 'main'.
and a text file 'def'. These two files constitute the program.

The first command in !Runimage

#include bob:string.hidden

loads in the library file !Armbob.Lib.string.hidden that defines
the function for hidden input. Its second,

#include <Acc$Dir>.def

loads in the definition of the class 'account'.

It is very convenient to organize programs up in this way, with a main
part and separate library parts, either supplied within !Armbob.Lib
or by your own application.

ArmBob uses the C convention for comments, enclosed in /* ... */.  Beware! You
cannot nest C comments. You can also put comments in ArmBob following //. Such
comments simply extend to the rest of the line.

The definition of the class called 'account' is defined by four pieces of data:

           balance;       
           owner;
           password;
           starting_date;

and four methods

           withdraw(x); 
           statement();
           change_password();
           has_owner(name);

The next definition

account::account(amount,name)
          {
           balance = (amount>0)?amount:0;
           owner = name;
           print("Enter ",name,"'s password here: ");
           password = hidden_input('-');
           starting_date = sysvar("Sys$Date");
           return this;
          }

describes how to create a particular account. A statement of the form

          slushfund = new account(1000,"Croesus");

in a program would use this definition to create an instance object
of the account class, called slushfund, with an initial balance of
1000 and an owner called "Croesus". The execution of the statement
would produce as a side-effect a request for a password, and would
use the operating system variable Sys$Date to establish slushfund's
starting date. The variables balance, owner, password and starting_date
have no meaning except in the context of a particular instance object
of account. Each instance object has its own copy of these variables.
To access them, for reading or writing, we have to use a method.
The next definition in Bob:h.account defines the withdraw method.

          account::withdraw(x)
          {
           local sum;
           print("Please enter your password :");
           if (password == hidden_input('-'))
             {
              sum = (x < balance)?x:balance;
              balance -= sum;
              print("\n",owner,"'s account has been debited ",sum,".\n");
             }
           else
            {
             sum = 0;
             print("\nSorry! Wrong password.\n");
            }
           return sum;
          }

If we wanted to withdraw, say 100, from Croesus' slushfund, we would
use the statement

         slushfund->withdraw(100);

When this statement is executed, the computer asks for a password. If
it does not get the right reply, no withdrawal takes place. The
expression

          slushfund->withdraw(100)

evaluates to the sum actually withdrawn. This may be different from
the sum requested (100 in this case), if the wrong password is given
or the current balance cannot fully meet the request.

You can interpret the '->' as an operator which joins an expression
for an instance object of a class with a method of that class to give 
an actual function. In the same way, you can think of the '::' symbol
as an operator that "opens up" the class that appears to the left of it
so that the data in the class is visible in the body of the method
whose name appears to the right of it.

It is a convention borrowed from C++, that the method for creating an
instance object always has the same name as the class itself. The word
'this' in a method refers to the instance object itself. The word 'new'
is used to allocate memory for a new instance object.

The first line in the body of the withdraw method

           local sum;

declares 'sum' to be a local variable. The keyword 'local' can only
occur once in a method or function definition, and then it has to
appear as the first word. To declare lots of variables local one must
write

          local x, y, ...... ;

with the variables separated by commas. Local variables are private
to the function definition that they appear in.

The statement and change_password methods are straightforward. The
has_owner method is used to look up which instance objects of the account
class belong to a given owner.

Next we will look at !Account.!RunImage.

